package com.guimin.user.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.guimin.common.util.SnowflakeIdWorker;
import com.guimin.common.util.exception.BaseException;
import com.guimin.user.constant.UserConstant;
import com.guimin.user.dao.UserInfoDao;
import com.guimin.user.dto.LoginInfoDto;
import com.guimin.user.entity.UserInfo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * 用户信息表(user_info)表服务实现类
 *
 * @author hzy
 */
@Slf4j
@Service("userInfoService")
@Transactional(rollbackFor = Exception.class)
public class UserInfoService extends ServiceImpl<UserInfoDao, UserInfo> {
    @Resource
    private UserInfoDao userInfoDao;

    /**
     * redis
     */
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 雪花id生成器
     */
    private SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0);

    /**验证码,验证码成功*/
    private static final String VERIFY="verify";
    private static final String VERIFIED="verifyed";

    /**
     * 手机号是否已注册
     * @param phone 手机号
     */
    public boolean userIsExist(String phone) {
        return null != super.getOne(new LambdaQueryWrapper<UserInfo>()
                .select(UserInfo::getPhone)
                .eq(UserInfo::getPhone, phone)
        );
    }

    /**
     * 手机号验证码验证
     * @param phone 手机号
     * @param verifyCode 验证码
     * @return 结果集
     */
    public String phoneVerify(@RequestParam @NotBlank(message = "校验手机号不能为空") @Size(min = 11, max = 11) String phone,
                              @RequestParam @NotBlank(message = "校验验证码不能为空") @Size(min = 4, max = 8) String verifyCode){
        //手机号校验
        String code = (String) redisTemplate.opsForValue().get(VERIFY + phone);
        if (code==null){
            return "验证码已过期";
        }
        if (!code.equals(verifyCode)){
            return "验证码错误";
        }
        redisTemplate.delete(VERIFY + phone);
        //设置验证成功的有效时间：5min
        redisTemplate.opsForValue().set(VERIFIED + phone,"true",5, TimeUnit.MINUTES);
        return "验证成功";
    }


    /**
     * 登录
     * @param login
     * @return
     */
    public LoginInfoDto login(LoginInfoDto login) {
        if (login.getPhone() == null || login.getPhone().isEmpty()) {
            throw new BaseException("手机号不能为空");
        }
        UserInfo user = super.getOne(new LambdaQueryWrapper<UserInfo>()
                .select(UserInfo::getId, UserInfo::getPhone, UserInfo::getState, UserInfo::getRole, UserInfo::getUsername)
                .eq(UserInfo::getPhone, login.getPhone())
                .ne(UserInfo::getState, UserConstant.State.USELESS.toString())
        );
        if (null == user) {
            throw new BaseException("未知用户");
        } else if (UserConstant.State.FROZEN.name().equals(user.getState())) {
            throw new BaseException("账号已冻结");
        } else if (UserConstant.State.AUDIT.name().equals(user.getState())) {
            throw new BaseException("账号审核中");
        }
        //生成登录用户信息
        login.setId(user.getId());
        login.setLoginTime(new Date());
        login.setState(user.getState());
        login.setRole(user.getRole());
        login.setUsername(user.getUsername());
        return login;

    }


    /**
     * 注册用户
     * @param loginDto
     * @return
     */
    public UserInfo register(LoginInfoDto loginDto) {

        //手机号正则校验
        if ((loginDto.getPhone() != null) && (!loginDto.getPhone().isEmpty())) {
            boolean matches = Pattern.matches("^1[3-9]\\d{9}$", loginDto.getPhone());
            if(matches == false){
                throw new BaseException("请输入正确的手机号");
            }
        }

        UserInfo userInfo = new UserInfo();
        //生成雪花ID
        long userId = snowflakeIdWorker.nextId();
        userInfo.setId(userId);//id
        userInfo.setPhone(loginDto.getPhone());//手机号
        if (loginDto.getRole() == null){
            userInfo.setRole(UserConstant.Role.PERSON.name());//角色
        }else {
            userInfo.setRole(loginDto.getRole());//角色
        }
        userInfo.setCreateDatetime(new Date());//创建时间
        userInfo.setUsername(loginDto.getPhone()+"用户");
        userInfo.setState(UserConstant.State.NORMAL.name());//状态
        int insert = userInfoDao.insert(userInfo);
        if(insert>0){
            return userInfo;
        }else {
            return null;
        }

    }
}